package org.visionlibrary.image.filters.effects;

import javax.media.jai.TiledImage;

import org.visionlibrary.image.acquisition.ImageFactory;
import org.visionlibrary.image.colormodel.HSVConverter;
import org.visionlibrary.image.colormodel.RGBConverter;
import org.visionlibrary.image.model.AbstractFilter;


public class PosterizeSpecial2 extends AbstractFilter {
	private float sepsilon = 0.25f;
	private float vepsilon = 0.25f;
	
	@Override
	public TiledImage applyFilter(TiledImage src, TiledImage dest) {
		if (null == src)
			throw new NullPointerException("Source image is null.");

		if (null == dest)
			dest = (new ImageFactory()).createCompatibleImage(src);
		
		int[] newHue = new int[360];
		
		java.util.Arrays.fill(newHue, 0, 21, 0); //czerwony
		java.util.Arrays.fill(newHue, 21, 31, 25); //pomarancz
		java.util.Arrays.fill(newHue, 31, 71, 55); //zolty
		java.util.Arrays.fill(newHue, 71, 146, 110); //zielony
		java.util.Arrays.fill(newHue, 146, 196, 170); //jasny niebieski
		java.util.Arrays.fill(newHue, 196, 264, 230); //niebieski
		java.util.Arrays.fill(newHue, 264, 360, 0); //czerwony (w tym fiolet i roz)
		
		int maxX = src.getWidth();
		int maxY = src.getHeight();

		for (int x = 0; x < maxX; x++)
			for (int y = 0; y < maxY; y++) {
				float[] values = new float[src.getNumBands()];
				for (int ch = 0; ch < src.getNumBands(); ch++) {
					int pix = src.getSample(x, y, ch);
					values[ch] = (float) norm(0, 255, 0, 1, pix);
				}
				
				float[] hsv = (new HSVConverter()).convertFromTYPE_RGB(values);
				hsv[0] = (float) newHue[(int)hsv[0]];
				
				//zaokraglanie ???
				if((hsv[2] - vepsilon) <= 0.0f) {
					hsv[1] = 0.0f;
					hsv[2] = 0.0f; //wszystko ponizej value < 15 to czarne
				} else if((hsv[1] - sepsilon) <= 0.0f) {
					hsv[1] = 0.0f;
					hsv[2] = 1.0f; //jezeli saturacja niska to biale
				} else {
					hsv[1] = 1.0f;
					hsv[2] = 1.0f;
				}
							
				values = (new RGBConverter()).convertFromTYPE_HSV(hsv);
				
				for (int ch = 0; ch < src.getNumBands(); ch++) {
					int pix = (int) norm(0, 1, 0, 255, values[ch]);
					dest.setSample(x, y, ch, pix);
				}
			}
		
		return dest;
	}
	
	public double norm(double oMin, double oMax, double nMin, double nMax,
			double value) {
		double ratio = (double) (nMax - nMin) / (double) (oMax - oMin);
		double result = value;
		result -= oMin;
		result *= ratio;
		result += nMin;

		return result;
	}
}
